#ifndef _BUOLA_CV_IO_CKINECTDEVICE_OPENNI_H_
#define _BUOLA_CV_IO_CKINECTDEVICE_OPENNI_H_

#include <buola/buola.h>
#include <buola/threads/thread.h>
#include <buola/threads/condition_variable.h>
#include <buola/utility/usignal.h>
#include <buola/image/format.h>

#include <atomic>
#include <OpenNI.h>

namespace buola { namespace cvi {

class CKinectDevice
{
public:
    CKinectDevice(const openni::DeviceInfo &pInfo);
    ~CKinectDevice();
    
    void Start();
    void Stop();
    
    std::pair<img::CImage_rgb8,img::CImage_gray32f> GetOne();

    USignal<void(const img::CImage_rgb8&,const img::CImage_gray32f&)> sImages;
    
private:
    bool HasDepthStream();
    bool HasImageStream();
    bool HasIRStream();
    
    void Initialize();

    void OnThread();
    
    void DoStart();
    void DoStop();
    void DoIteration(int pCount);
    
private:
    openni::DeviceInfo mDeviceInfo;
    openni::Device mNIDevice;
    openni::VideoStream mNIDepth;
    openni::VideoStream mNIImage;
    openni::VideoStream mNIIR;
    
    std::atomic<bool> mInitialized;

    thread mThread;
    mutex mMutex;
    condition_variable mCondVar;

    int mSyncIndex;
    mutex mSyncMutex;
    condition_variable mSyncCondVar;
    img::CImage_rgb8 mSyncImageRGB;
    img::CImage_gray32f mSyncImageDepth;
    
    std::atomic<int> mStartCount;    
    
    bool mStarted;
};

/*namespace cvi*/ } /*namespace buola*/ }

#endif
